/**
 * 
 */
package steffens.java.gui.defaultui.bar;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.List;

import steffens.java.gui.defaultui.general.DefaultBar;
import steffens.java.gui.defaultui.interactive.buttons.DefaultButton;

/**
 * @author Steffen Baumann
 * @version 1.1 
 *
 */
public class ButtonBar extends DefaultBar {
	
	public static final int HORIZONTAL = 1;
	public static final int VERTICAL = 2;
	
	private int barOrientation = HORIZONTAL;
	
	
	public static final int NORTH = GridBagConstraints.PAGE_START;
	public static final int NORTH_EAST = GridBagConstraints.NORTHEAST;
	public static final int EAST = GridBagConstraints.EAST;
	public static final int SOUTH_EAST = GridBagConstraints.SOUTHEAST;
	public static final int SOUTH = GridBagConstraints.SOUTH;
	public static final int SOUTH_WEST = GridBagConstraints.SOUTHWEST;
	public static final int WEST = GridBagConstraints.LINE_START;
	public static final int NORTH_WEST = GridBagConstraints.NORTHWEST;
	public static final int CENTER = GridBagConstraints.CENTER;
	
	private int anchor = CENTER;
	
	private List<? extends DefaultButton> buttons = new ArrayList<>();
	private Container buttonContainer = new Container();
	
	private static final int DEFAULT_BUTTON_WIDTH = 96;
	private static final int DEFAULT_BUTTON_HEIGHT = 24;
	private Dimension buttonSize = new Dimension(DEFAULT_BUTTON_WIDTH, DEFAULT_BUTTON_HEIGHT);
	private static final int DEFAULT_INSET_X = 8;
	private static final int DEFAULT_INSET_Y = 8;
	private Dimension insets = new Dimension(DEFAULT_INSET_X, DEFAULT_INSET_Y);

	/**
	 * 
	 */
	public ButtonBar() {
		this(new ArrayList<DefaultButton>());
	}

	public ButtonBar(List<? extends DefaultButton> buttons) {
		this.buttons = buttons;
		setLayout();
		GridBagConstraints placement = getConstraints(anchor);
		addButtonContainer(getBarContainer(), placement);
	}

	private void setLayout(){
		Container container = getBarContainer();
		container.setLayout(new GridBagLayout());
		FlowLayout layout = new FlowLayout(FlowLayout.CENTER, insets.width, insets.height);
		buttonContainer.setLayout(layout);
	}
	
	@Override
	public void updateBar() {
		Container con = getBarContainer();
		Dimension minimalSize = getMinimumDimension();
		con.setMinimumSize(minimalSize);
		buttonContainer.setSize(minimalSize);
		con.setPreferredSize(minimalSize);
		
		validateBar(con);
		con.setBackground(getBackground());
		con.validate();
		
		Container parent = con.getParent();
		if(parent != null){
			parent.validate();
		}
		if(getParentNotifier() != null) getParentNotifier().notifyParentAboutCahnge();
		con.repaint();
		con.setVisible(true);
	}
	
	private void validateBar(Container con){
		con.removeAll();
		GridBagConstraints placement = getConstraints(anchor);
		addButtonContainer(con, placement);
	}
	private GridBagConstraints getConstraints(int anchor){
		GridBagConstraints placement = new GridBagConstraints();
		placement.gridx = 0;
		placement.gridy = 0;
		placement.weightx = 0.5;
		placement.weighty = 0.5;
		placement.fill = GridBagConstraints.HORIZONTAL;
		placement.anchor = anchor;
		return placement;
	}
	
	private void addButtonContainer(Container con, GridBagConstraints placement){
		
		for(int i = 0; i  < buttons.size(); i++){
			DefaultButton button = buttons.get(i);
			button.setSize(buttonSize);
			button.setPreferredSize(buttonSize);
			button.setMinimumSize(buttonSize);
			button.setMaximumSize(buttonSize);
			buttonContainer.add(button);
		}		
		Dimension buttonPanelSize = getButtonContainerDimension();
		buttonContainer.setSize(buttonPanelSize);
		buttonContainer.setPreferredSize(buttonPanelSize);
		buttonContainer.setMinimumSize(buttonPanelSize);
		buttonContainer.setMaximumSize(buttonPanelSize);
		con.add(buttonContainer, placement);
		
	}
	

	private Dimension getButtonContainerDimension() {
		int buttonWidth = buttonSize.width;
		int buttonHeight = buttonSize.height;
		int insetsHeight = insets.height;
		int insetsWidth = insets.width;
		Dimension buttonContainerSize = null;
		if(barOrientation == HORIZONTAL){
			buttonContainerSize = new Dimension(buttons.size()*(buttonWidth+insetsWidth)+insetsWidth,insetsHeight*2+buttonHeight);
			return buttonContainerSize;
		}else if(barOrientation == VERTICAL){
			buttonContainerSize = new Dimension(buttonWidth+2*insetsWidth, buttons.size()*(buttonHeight+insetsHeight)+insetsHeight);
			return buttonContainerSize;
		}else{
			throw new IllegalArgumentException();
		}
	}

	public Dimension getMinimumDimension(){
		return getButtonContainerDimension();
	}
	
	/**
	 * @return the barOrientation
	 */
	public int getBarOrientation() {
		return  barOrientation;
	}
	/**
	 * @param barOrientation the barOrientation to set
	 */
	public void setButtonOrientation(int barOrientation) {
		this.barOrientation = barOrientation;
		updateBar();
	}
	
	/**
	 * @return the anchor
	 */
	public int getButtonAnchor() {
		return anchor;
	}
	/**
	 * @param anchor the anchor to set
	 */
	public void setButtonAnchor(int anchor) {
		this.anchor = anchor;
		this.updateBar();
	}
	public void setButtonSize(Dimension buttonSize){
		this.buttonSize = buttonSize;
		updateBar();
	}
	public Dimension getButtonSize(){
		return this.buttonSize;
	}
}
